package com.effectiv.gooruda.rest.ext;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.core.MultivaluedMap;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import com.effectiv.gooruda.domain.Application;
import com.effectiv.gooruda.rest.domain.ApiRequestAuditEntry;


@Component
@Slf4j
public class InvocationAuditProcessor {
	
	@Autowired
	private MongoTemplate template;
	
	@Async
	public void logRequest(ContainerRequestContext reqCtx,
			ContainerResponseContext resCtx, Application application, String api, String remoteHost, String locale){
		log.info("--------- Hello I am looging invocation asynchronously ---------------");
		
		ApiRequestAuditEntry entry = BeanUtils.instantiate(ApiRequestAuditEntry.class);
		
		entry.setApiPath(reqCtx.getUriInfo().getAbsolutePath().toString());
		
		log.info("Base path = {}", reqCtx.getUriInfo().getPath());
		
		entry.setMethod(reqCtx.getMethod());
		entry.setHeaders(convert(reqCtx.getHeaders()));
		entry.setQueryParams(convert(reqCtx.getUriInfo().getQueryParameters()));
		entry.setMedia(reqCtx.getMediaType().getType());
		entry.setLanguage(locale);
		entry.setRemoteHost(remoteHost);
		entry.setApi(api);
		entry.setTenant(application.getTenant());
		entry.setApplication(application);
		
		template.save(entry);
	}
	
	private Map<String, String> convert(MultivaluedMap<String, String> data){
		Map<String,String> retMap = null;
		
		if(data != null && !data.isEmpty()) {
			retMap = new HashMap<String,String>();
			
			Iterator<String> keys = data.keySet().iterator();
			
			String key = null;
			
			while(keys.hasNext()){
				key = keys.next();
				retMap.put(key, data.getFirst(key));
			}
			
			
		}
		
		return retMap;
	}
}
